﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SharedComponents;

namespace OurLeague.Object
{
    public class Team
    {
        #region Fields

        String _name;
        String _teamId;
        String _teamName;
        String _registeredOffice;
        String _president;
        String _stadiumName;

        List<String> _players;
        String _coachId;

        public static List<Team> Teams = new List<Team>();

        #endregion

        #region Constructors

        
        public Team(String teamName, String headquartes, String president, String stadiumName, String teamID, List<Player> players, Coach coach)
        {

        }
        

        public Team()
        {

        }

        #endregion

        #region Public Methods

        public bool delete()
        {
            if (!MySqlQueryHelper.deleteQuery(MySqlManager.Connection, "Teams", "teamId", new String[] { Id }))
                return false;
            
            Teams.Remove(this);
            Player.removeAll(this);
            return true;
        }

        public void save()
        {
            MySqlRecord updateRecord = new MySqlRecord();

            updateRecord["name"]= Name;
            updateRecord["registeredOffice"] = RegisteredOffice;
            updateRecord["stadium"] = Stadium;
            updateRecord["president"] = President;
            updateRecord["fkCoachId"] = CoachId;

            if (!Teams.Exists(t => t.Id == Id))
            {
                Teams.Add(this);
                Id = MySqlQueryHelper.saveQuery(MySqlManager.Connection, "Teams", null, updateRecord).ToString();

                MySqlQueryHelper.saveQuery(MySqlManager.Connection, "Teams", null, updateRecord);

                return;
            }

            MySqlQueryHelper.saveQuery(MySqlManager.Connection, "Teams", "teamId=" + Id, updateRecord);
        }

        public List<Booked> getYellowCardList()
        {
            var yellowCardList = new List<Booked>();
            foreach (Event e in Event.Events)
            {
                if (e.Player.TeamId == Id && e.Type == 2)
                {
                    var bookedPlayer = yellowCardList.Find(b => b.Player.Id == e.Player.Id);
                    if (bookedPlayer != null)
                        bookedPlayer.incYellowCardN();
                    else
                        yellowCardList.Add(new Booked(e.Player, 1, e.Player.TeamName));
                }
            }

            return yellowCardList;
        }

        public List<Expelled> getRedCardList()
        {
            var redCardList = new List<Expelled>();
            foreach (Event e in Event.Events)
            {
                if (e.Player.TeamId == Id && e.Type == 3)
                {
                    var expelledPlayer = redCardList.Find(r => r.Player.Id == e.Player.Id);
                    if (expelledPlayer != null)
                        expelledPlayer.incRedCardN();
                    else
                        redCardList.Add(new Expelled(e.Player, 1, e.Player.TeamName));
                }
            }

            return redCardList;
        }

        public List<Scorer> getScorerList()
        {
            var scorelist = new List<Scorer>();
            foreach (Event e in Event.Events)
            {
                var scorer = scorelist.Find(s => s.Player.Id == e.Player.Id);
                if (e.Player.TeamId == Id && e.Type == 1)
                    if (scorer != null)
                        scorer.increaseGoalNumber();
                    else
                        scorelist.Add(new Scorer(e.Player, 1, e.Player.TeamName));
            }
            return scorelist;
        }

        public List<PlayTime> getPlayedTimeList()
        {
            var playerPlayedTimeList = new List<PlayTime>();
            var teamLineUp = LineUp.LineUps.Where(lu => lu.TeamId == Id).ToList();
            foreach (LineUp lineUp in teamLineUp)
            {
                foreach (Player player in lineUp.RegularPlayers)
                {
                    var playerPT = playerPlayedTimeList.Find(pt => pt.Player.Id == player.Id);
                    if (playerPT == null)
                    {
                        playerPlayedTimeList.Add(new PlayTime(player, 90, player.TeamName));
                        playerPT = playerPlayedTimeList.Last();
                    }
                    else
                        playerPT.addMinutes(90);

                    var playerEvents = Event.Events.Where(e => e.Type == 5 && e.Player.Id == player.Id).ToList();

                    if (playerEvents.Count > 0)
                        playerPT.addMinutes(-1 * (playedMinute(playerEvents.First().Half, playerEvents.First().Minute)));
                }

                foreach (Player player in lineUp.ReservePlayers)
                {
                    var playerEvents = Event.Events.Where(e => e.Type == 4 && e.Player.Id == player.Id);

                    if (playerEvents.Count() > 0)
                    {
                        int minutePlayed = playedMinute(playerEvents.First().Half, playerEvents.First().Minute);
                        var substitution = Event.Events
                            .Where(e => e.Type == 5 && e.Player.Id == player.Id && e.MatchId == playerEvents.First().MatchId);

                        if (substitution.Count() > 0)
                            minutePlayed -= playedMinute(substitution.First().Half, substitution.First().Minute);

                        var playerPT = playerPlayedTimeList.Find(pt => pt.Player.Id == player.Id);
                        if (playerPT == null)
                            playerPlayedTimeList.Add(new PlayTime(player, minutePlayed, player.TeamName));
                        else
                            playerPT.addMinutes(minutePlayed);
                    }
                }
            }
            
            return playerPlayedTimeList;
        }

                /*
        public void update(String str)
        {

        }

        public void view()
        {

        }

        public void viewPlayer(String player)
        {

        }

        public void deletePlayer(String player)
        {

        }

        public void insertPlayer(String str, String str2, int a, String str3, String str4, int b, int c)
        {

        }

        public void editPlayer(String str, String str2, int a, String str3, String str4, int b, int c, String str5)
        {

        }

        public Boolean findPlayer(String player)
        {
            return false;
        }

        public Boolean findTeam(String team)
        {
            return false;
        }
        */
        #endregion

        #region Private Methods

        private int playedMinute(int half, int eventMinute)
        {
            return (45 * (half == 1 ? 1 : 0) + 45 - eventMinute);
        }

        #endregion

        #region Properties

        public String Name
        {
            get { return _name; }
            set { _name = value; }
        }

        public String Id
        {
            get { return _teamId; }
            set { _teamId = value; }
        }

        public String TeamName
        {
            get { return _teamName; }
            set { _teamName = value; }
        }

        public String RegisteredOffice
        {
            get { return _registeredOffice; }
            set { _registeredOffice = value; }
        }

        public String President
        {
            get { return _president; }
            set { _president = value; }
        }

        public String Stadium
        {
            get { return _stadiumName; }
            set { _stadiumName = value; }
        }

        public String CoachId
        {
            get { return _coachId; }
            set { _coachId = value; }
        }

        public List<String> PlayersID
        {
            get { return _players; }
            set { _players = value; }
        }

        public List<Player> Players
        {
            get 
            {
                var players = new List<Player>();
                foreach (String player in PlayersID)
                {
                    players.Add(Player.load(player));
                }

                return players;
            }
        }

        #endregion

        #region Static Methods

        public static void loadAll()
        {
            var queryResult = MySqlQueryHelper.selectQuery(MySqlManager.Connection, "Teams", null, null);
            foreach (MySqlRecord teamRecord in queryResult)
            {
                if (Teams.Find(T => T.Id == teamRecord["teamId"].ToString()) == null)
                    addNewTeam(teamRecord);
            }
        }

        public static Team load(String idTeam)
        {
            Team team = Teams.Find(p => p.Id == idTeam);

            if (team == null)
            {
                var queryResult = MySqlQueryHelper.selectQuery(MySqlManager.Connection, "Teams", null, "teamId=" + idTeam);
                team = addNewTeam(queryResult[0]);
            }

            return team;
        }

        private static Team addNewTeam(MySqlRecord teamRecord)
        {
            Team team = new Team();
            team.Id = teamRecord["teamId"].ToString();
            team.Name = teamRecord["name"].ToString();
            team.RegisteredOffice = teamRecord["registeredOffice"].ToString();
            team.President = teamRecord["president"].ToString();
            team.Stadium = teamRecord["stadium"].ToString();
            team.CoachId = teamRecord["fkCoachId"].ToString();

            var queryResult = MySqlQueryHelper.selectQuery(MySqlManager.Connection, "Players", null, "fkTeamId=" + teamRecord["teamId"].ToString());
            List<String> players = new List<String>();

            foreach (MySqlRecord playerRecord in queryResult)
            {
                players.Add(playerRecord["playerId"].ToString());
            }

            team.PlayersID = players;

            Teams.Add(team);

            return team;
        }

        public static Team getTeamFromName(String name)
        {
            Team team = Teams.Find(t => t.Name == name);
            if (team == null)
            {
                var teamRecord = MySqlQueryHelper
                    .selectQuery(MySqlManager.Connection, "Teams", new String[] { "teamId" }, "name ='"+ name + "'")[0];
                team = load(teamRecord["teamId"].ToString());
            }

            return team;
        }

        public static bool canPlay(string idTeam) 
        {
            List<Player> pl = Player.Players.FindAll(P => P.TeamId == idTeam && P.isAvailable());
            if ((pl.Count >= (LineUp.REGULAR + LineUp.RESERVE)) && (pl.FindAll(P => P.Role.ToLower().Trim().Equals("portiere")).Count >= 2))
                return true;
            return false;
        }
        #endregion
    }
}
